<?php

namespace plugin\muadmin\app\common\core;

use think\facade\Db;

class DbHand
{
    protected static $instance;
    protected $error = '';
    protected $cnn  = null;
    protected $databaseType = 'mysql';

    public static function instance(array $config=[])
    {
        if (!self::$instance) {
            self::$instance = new self($config);
        }
        return self::$instance;
    }
    public function getError()
    {
        return  $this->error;
    }
    public function __destruct()
    {
        if($this->cnn){
            @mysqli_close($this->cnn);
        }

    }
    public function has_sqlit_db($type,$databses)
    {
        $this->databaseType = $type;
        $file = base_path().$databses;
//        print_r($file);
        if(!is_file($file)){
            if(!is_dir(dirname($file))){
                mkdir(dirname($file), 0777, true);
            }
            file_put_contents($file, '');
        }
        if(empty($this->cnn)){
            $conn = 'sqlite:'.$file;
            $this->cnn = new \PDO($conn,  '', '', []);
        }
        return true;
    }
    /**
     * 判断是否有数据库
     * @param $type
     * @param $hostname
     * @param $hostport
     * @param $username
     * @param $password
     * @param $charset
     * @param $collation
     * @return bool
     */
    public function has_db($type,$hostname,$hostport,$username,$password,$charset,$collation='utf8mb4_general_ci')
    {
        $this->databaseType = $type;
        if($type=='mysql'){
//            var_dump(function_exists("mysqli_connect"));
            if(!function_exists("mysqli_connect")){
                $this->error = "请安装php-mysqli扩展";
                return false;
            }
            $dbhost = $hostname.':'.$hostport;
//            print_r($dbhost);
            $conn = @mysqli_connect($dbhost, $username, $password);
            if(empty($conn)){
                $this->error = "数据库连接失败";
                return false;
            }
            $this->cnn  = $conn;
            return true;
        }
        return true;
    }

    /**
     * 检查是否存在数据库
     * @param string $database_name
     * @return bool
     */
    public function has_database(string $database_name)
    {
        $sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$database_name'";
        $result = $this->cnn->query($sql);
        if($result){
            if($result->num_rows > 0){
                return true;
            }
        }
        return false;
    }

    /**
     * 创建数据库
     * @param $database_name
     * @param $charset
     * @param $collation
     * @return bool
     */
    public function change_database($database_name,$charset,$collation='utf8mb4_general_ci')
    {
        if($this->databaseType=='mysql'){
            $res = $this->has_database($database_name);
            if($res===false){
                $sql = "CREATE DATABASE IF NOT EXISTS `{$database_name}` DEFAULT CHARACTER SET {$charset} COLLATE {$collation};";
                $res = $this->cnn->query($sql);
                if($res===false){
                    return false;
                }
                $this->cnn->select_db($database_name);
                return true;
            }else{
                $sql = "DROP DATABASE {$database_name}";
                $res = $this->cnn->query($sql);
                if($res===false){
                    return false;
                }
                $sql = "CREATE DATABASE IF NOT EXISTS `{$database_name}` DEFAULT CHARACTER SET {$charset} COLLATE {$collation};";
                $res = $this->cnn->query($sql);
                if($res===false){
                    return false;
                }
                $this->cnn->select_db($database_name);
                return true;
            }
        }elseif ($this->databaseType=='sqlite'){
            return is_file(base_path().$database_name);
        }
    }

    /**
     * 更新sql
     * @param $filePath
     * @param $dbprefix
     * @return bool
     * @throws \Exception
     */
    public function update_sql($filePath,$dbprefix='')
    {
        if(!is_file($filePath)){
            return false;
        }
        $get_sql_data = file_get_contents($filePath);
        $get_sql_data = str_replace("__PREFIX__", $dbprefix, $get_sql_data);
        $sql_query = $this->getSqlQuery($get_sql_data);
        $query_count = count($sql_query);
        for ($i = 0; $i < $query_count; $i++) {
            $sql = trim($sql_query[ $i ]);
            $is_write = false;
            if (str_contains($sql, 'CREATE TABLE')) {
                $match_item = preg_match('/CREATE TABLE [`]?(\\w+)[`]?/is', $sql, $match_data);
                $is_write = true;
            } elseif (str_contains($sql, 'ALTER TABLE')) {
                $match_item = preg_match('/ALTER TABLE [`]?(\\w+)[`]?/is', $sql, $match_data);

            } elseif (str_contains($sql, 'INSERT INTO')) {
                $match_item = preg_match('/INSERT INTO [`]?(\\w+)[`]?/is', $sql, $match_data);
            } else {
                $match_item = 0;
            }
            if ($match_item > 0) {
                try {
                    $table_name = $match_data[ 1 ];
                    $new_table_name = $table_name;
                    $sql_item = $this->str_replace_first($table_name, $new_table_name, $sql);
                    if($this->databaseType=='mysql'){
                        @mysqli_query($this->cnn, $sql_item);
                    }else{
                        print_r($sql_item);
                        $this->cnn->exec($sql_item);
                    }

                } catch (\Exception $e) {
                    throw new \Exception($e->getMessage());
                }
            }
        }
        return true;
    }
    protected function str_replace_first($search, $replace, $subject)
    {
        return implode($replace, explode($search, $subject, 2));
    }
    protected function getSqlQuery($sql_data)
    {
//        $this->checkLock();
        $sql_data = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=utf8", $sql_data);

        $sql_data = str_replace("\r", "\n", $sql_data);
        $sql_query = [];
        $num = 0;
        $sql_arr = explode(";\n", trim($sql_data));
        unset($sql);
        foreach ($sql_arr as $sql) {
            $sql_query[ $num ] = '';
            $sqls = explode("\n", trim($sql));
            $sqls = array_filter($sqls);
            foreach ($sqls as $query) {
                $str1 = $query[ 0 ] ?? '';
                if ($str1 != '#' && $str1 != '-')
                    $sql_query[ $num ] .= $query;
            }
            $num++;
        }
        return $sql_query;
    }

}